// opt: 3
#include "src/pasex.hh"
#include "src/parse.hh"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define ALL_TOKEN 0
#define PARSE 1

int main()
{
	std::ifstream fin{"3-grammar"};
	std::ifstream pin{"input-program"};
	lex::regular_grammar g;
	fin >> g;
	lex::nfa::nfa n(g);
	lex::dfa::dfa d(n);
	/*
	std::ofstream nfa_out{"nfa-out.dot"};
	std::ofstream dfa_out{"dfa-out.dot"};
	n.print(nfa_out);
	d.print(dfa_out);
	*/

	std::string code;
	std::string t;
	for (; pin >> t; code += t) if (code.size()) code +="^";

	std::ifstream parin{"2-grammar"};
	parse::context_free_grammar cfg;
	parin >> cfg;
	parse::lr_set_dfa lsd(cfg);

/*
	std::cout << "===============================================\n";
	std::cout << "sr confict count = " << lsd.sr_conflict_count() << '\n';
	std::cout << "rr confict count = " << lsd.rr_conflict_count() << '\n';
	std::cout << " state of lr dfa = " << lsd.size() << '\n';
*/

#if ALL_TOKEN
	d.lex(code);
#endif

#if PARSE
	if (lsd.parse(code, d)) std::cout << "\e[1;32m[ OK ]\e[0;32m no error occured.\e[0m\n";
#endif

}

#undef PARSE
#undef ALL_TOKEN

